/**
 * Copyright 2018 orivil.com. All rights reserved.
 * Use of this source code is governed by a MIT-style
 * license that can be found at https://mit-license.org.
 */

package mux

import (
	"encoding/json"
	"gitee.com/tugoer/orivil/config"
	"gitee.com/tugoer/orivil/log"
	"gitee.com/tugoer/orivil/uuid"
	"os"
	"time"
)

// TODO: 将初始化方法从 init 函数中移除
type server struct {
	Debug         bool          `json:"debug"`
	LogCostTime   bool          `json:"log_cost_time"`
	CacheTemplate bool          `json:"cache_template"`
	ViewDir       string        `json:"view_dir"`
	TemplateExt   string        `json:"template_ext"`
	ServeTimeOut  time.Duration `json:"serve_time_out"`  // in seconds
	LimitPostBody int64         `json:"limit_post_body"` // in KB
	Key           string        `json:"key"`             // server unique key
}

type listen struct {
	HttpPort          string `json:"http_port"`
	HttpsPort         string `json:"https_port"`
	ServerName        string `json:"server_name"`
	SSL               bool   `json:"ssl"`
	SSLCertificate    string `json:"ssl_certificate"`
	SSLCertificateKey string `json:"ssl_certificate_key"`
}

func (l listen) Addr() string {
	if l.SSL {
		return "https://" + l.ServerName + l.HttpsPort
	} else {
		return "http://" + l.ServerName + l.HttpPort
	}
}

func (l listen) Host() string {
	if l.SSL {
		return "https://" + l.ServerName
	} else {
		return "http://" + l.ServerName
	}
}

type dir struct {
	Views   string `json:"views"`
	Configs string `json:"configs"`
	I18n    string `json:"i_18_n"`
}

type languages struct {
	Default string     `json:"default"`
	Lists   []language `json:"languages"`
}

type language struct {
	Abbr string `json:"abbr"`
	Name string `json:"name"`
}

type env struct {
	Server    server
	Listen    listen
	Dir       dir
	Languages languages
}

var Env = initEnv()

func initEnv() *env {
	e := &env{
		Server: server{
			Debug:         true,
			LogCostTime:   true,
			CacheTemplate: false,
			ViewDir:       "views",
			TemplateExt:   ".gohtml",
			ServeTimeOut:  10,       // 10S
			LimitPostBody: 10 << 10, // 10MB
			Key:           uuid.New(),
		},

		Listen: listen{
			HttpPort:   ":8080",
			ServerName: "localhost",
			HttpsPort:  ":443",
		},

		Languages: languages{
			Default: "zh_CN",
			Lists: []language{
				{
					Abbr: "zh_CN",
					Name: "简体中文",
				},
				{
					Abbr: "en",
					Name: "English",
				},
			},
		},

		// dir 是固定值不可配置
		Dir: dir{
			Views:   "views",
			Configs: "configs",
			I18n:    "i18n",
		},
	}
	var dirs map[string]string
	data, _ := json.Marshal(e.Dir)
	json.Unmarshal(data, &dirs)
	for _, dir := range dirs {
		err := os.MkdirAll(dir, 0666)
		if err != nil {
			panic(err)
		}
	}

	parser := config.NewJsonParser("configs")

	err := parser.ReadOrCreate("server", &e.Server)
	if err != nil {
		panic(err)
	}
	if e.Server.Debug {
		log.Warning.Println("server is running on debug mode")
	}
	e.Server.LimitPostBody = e.Server.LimitPostBody << 10       // turn to KB
	e.Server.ServeTimeOut = e.Server.ServeTimeOut * time.Second // turn to Second

	err = parser.ReadOrCreate("listen", &e.Listen)
	if err != nil {
		panic(err)
	}

	err = parser.ReadOrCreate("languages", &e.Languages)
	if err != nil {
		panic(err)
	}
	return e
}
